/**
 * Created with IntelliJ IDEA.
 * User: aermakov
 * Date: 23.05.13
 * Time: 15:23
 * To change this template use File | Settings | File Templates.
 */

Ext.ns('GrailsCompany.form');

Ext.define('GrailsCompany.form.FormHelper', {
    /**
     * The hierarchy of Forms is as follows:
     * intent (i.e. details, create)
     *      domain (i.e. Employee)
     *          form
     */
    Forms: {
        details: {
            Employee: {
                information: {xtype: 'employeeform'},
                financial: {xtype: 'employeefinform'}
            },
            Project: {
                information: {xtype: 'prjform'}
            },
            Department: {
                information: {xtype: 'orgform'}
            },
            Organization: {
                information: {xtype: 'orgform'}
            }
        },
        create: {
            Employee: {
                information: {xtype: 'employeeform'},
                financial: {xtype: 'employeefinform'}
            },
            Project: {
                information: {xtype: 'prjform'}
            },
            Department: {
                information: {xtype: 'orgform'}
            },
            Organization: {
                information: {xtype: 'orgform'}
            }
        }
    },

    constructor: function (config) {
        Ext.applyIf(this, config);
        this.DH = GrailsCompany.data.DH;
        this.createForms();
    },

    createForms: function () {
        for (var intent in this.Forms) {
            for (var domain in this.Forms[intent]) {
                for (var item in this.Forms[intent][domain]) {
                    var config = this.Forms[intent][domain][item];

                    Ext.apply(config, {
                        intent: intent,
                        padding: 30,
                        listeners: {
                            crudbatch: {fn: this.handleCRUDAction, scope: this}
                        },
                        multiTabs: Object.keys(this.Forms[intent][domain]).length > 1
                    });
                    // configForDetails, configForCreate
                    this['configFor' + Ext.util.Format.capitalize(intent)](domain, item, config);
                    var form = Ext.create(config);
                    this['postConfigFor' + Ext.util.Format.capitalize(intent)](domain, item, form);
                    var container = Ext.create({
                        xtype: 'panel',
                        autoDestroy: false,
                        title: Ext.util.Format.capitalize(item),
                        itemId: item,
                        items: [ form ]
                    });
                    this.Forms[intent][domain][item] = {
                        form: form,
                        panel: container
                    }
                }
            }
        }
    },

    configForDetails: function (domain, item, config) {
        Ext.apply(config, {
            actions: ['update', 'delete']
        });
    },

    postConfigForDetails: Ext.emptyFn,

    configForCreate: function (domain, item, config) {
        Ext.apply(config, {
            actions: ['create', 'cancel']
        });
    },

    postConfigForCreate: function (domain, item, form) {
        form.storeId = Ext.util.Format.lowercase(domain);
        var store = Ext.StoreMgr.get(form.storeId);
        if (store.parentStoreId) {
            form.add(new Ext.form.ComboBox({
                store: Ext.StoreMgr.get(store.parentStoreId),
                valueField: 'id',
                name: 'parentId',
                hiddenName: 'parentId',
                displayField: 'title',
                fieldLabel: 'Parent',
                mode: 'local',
                allowBlank: false,
                editable: false
            }));
        }
        form.on('click', function (o, args) {
            if (args.action === 'cancel') {
                this.createWindow.hide();
            }
        });
        form.on('done', function() {
            this.createWindow.hide();
        }, this);
    },

    handleCRUDAction: function (storeId, recordId, action, values) {
        var a = this.activeAction;
        if (a.storeId !== storeId) {
            return;
        }

        var forms = this.Forms[a.intent][a.domain];
        for (var tab in forms) {
            var form = forms[tab].form.getForm();
            if (!form.isDirty()) continue;
            if (!form.isValid()) {
                a.activate(forms[tab].panel)
                return;
            }
            Ext.apply(values, form.getValues());
        }

        switch (action) {
            case 'update':
                this.DH.update(a.storeId, a.recordId, values);
                break;
            case 'create':
                this.createWindow.close();
                this.DH.create(a.storeId, values);
                break;
        }
    },

    activeAction: {
        intent: '',
        domain: '',
        storeId: '',
        recordId: 0,
        values: undefined,
        activate: Ext.emptyFn
    },

    showDetails: function (storeId, record) {
        var domain = Ext.util.Format.capitalize(storeId);
        var intent = 'details';
        var forms = this.Forms[intent][domain];
        var container = Ext.getCmp('detailsPanel');
        Ext.apply(this.activeAction, {
            intent: intent,
            domain: domain,
            storeId: storeId,
            recordId: record.id,
            activate: function (cmp) {
                container.activate(cmp);
            }
        });

        var removed = container.removeAll(false);
        Ext.each(removed, function (cmp) {
            // XXX Manually hide removed panels as we didn't destroy them.
            cmp.hide();
        }, this);
        container.doLayout();
        for (var tab in forms) {
            var item = forms[tab];
            item.form.getForm().loadRecord(record);
            Ext.apply(item.form, {
                recordId: record.id,
                storeId: storeId
            });
            container.add(item.panel);
        }
        container.doLayout();
        container.activate(0);
    },

    showCreate: function (storeId) {
        var domain = Ext.util.Format.capitalize(storeId);
        var intent = 'create';
        var forms = this.Forms[intent][domain];
        this.createWindow = Ext.create(this.createWindowConfig);
        var container = Ext.getCmp('createPanel');
        Ext.apply(this.activeAction, {
            intent: intent,
            domain: domain,
            storeId: storeId,
            activate: function (cmp) {
                container.activate(cmp);
            }
        });

        var removed = container.removeAll(false);
        Ext.each(removed, function (cmp) {
            // XXX Manually hide removed panels as we didn't destroy them.
            cmp.hide();
        }, this);
        for(var tab in forms) {
            var item = forms[tab];
            item.form.getForm().reset();
            container.add(item.panel);
        }
        container.doLayout();
        container.activate(0);

        this.createWindow.show();
    },

    createWindowConfig: {
        xtype: 'window',
        layout: 'fit',
        width: 400,
        height: 300,
        padding: 10,
        autoDestroy: false,
        border: false,
        closeAction: 'hide',
        items: [
            {
                id: 'createPanel',
                xtype: 'tabpanel',
                autoDestroy: false,
                border: false
            }
        ],
        modal: true,
        resizable: false
    }
});

GrailsCompany.form.FH = function () {
    return new GrailsCompany.form.FormHelper;
}();